#include "myUtil.h"
#include "btnManager.h"
#include "editManager.h"
#include "timerManager.h"
#include "winProcCallBacks.h"
#include "ttMsgMap.h"
#include "Me.h"
#include "ttClientPrxMgr.h"
#include "edit_Impl.h"
#include "autoLock.h"

DEFWNDRPOC(msgProc);
DEFWNDRPOC(msgWndProc);

int 
onDefault::runShell(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	return run(hwnd, message, wParam, lParam); 
}

int 
onDefault::run(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	return DefWindowProc(hwnd, message, wParam, lParam);
}

IMPLFUNC(onCreate, WM_CREATE)
{
    myUtil::testoutput("onCreate");
	btnManager::Get()->CreateSubWindows(hwnd);
	editManager::Get()->CreateSubWindows(hwnd);
	

	WNDCLASS wndclass ;
    wndclass.style        = CS_HREDRAW | CS_VREDRAW ;
    wndclass.lpfnWndProc  = msgWndProc ;
    wndclass.cbClsExtra   = 0 ;
    wndclass.cbWndExtra   = 0 ;
	wndclass.hInstance    = ttMsgMap::Get()->m_msglpvar.m_MainInstance ;
    wndclass.hIcon        = LoadIcon (NULL, IDI_APPLICATION) ;
    wndclass.hCursor      = LoadCursor (NULL, IDC_ARROW) ;
    wndclass.hbrBackground= (HBRUSH) GetStockObject (WHITE_BRUSH) ;
    wndclass.lpszMenuName = NULL ;
    wndclass.lpszClassName= TEXT("msgWnd") ;
	if (!RegisterClass (&wndclass))
    {
        MessageBox (  NULL, TEXT ("This program requires Windows NT!"),
            TEXT("msgWnd"), MB_ICONERROR) ;
        return NULL ;
    }

	ttMsgMap::Get()->m_msglpvar.m_hMsg = CreateWindowEx(WS_EX_TOOLWINDOW, TEXT("msgWnd"), NULL, 
		 WS_POPUP,
		 0, 0, 100, 20, NULL, NULL, ttMsgMap::Get()->m_msglpvar.m_MainInstance, NULL);
	ShowWindow (ttMsgMap::Get()->m_msglpvar.m_hMsg, SW_HIDE) ;
	UpdateWindow (ttMsgMap::Get()->m_msglpvar.m_hMsg) ;
	ttMsgMap::Get()->m_msglpvar.m_bMsgHavEdit = false;

	InitializeCriticalSection(&(ttMsgMap::Get()->m_msglpvar.m_csMsgList));

	return 1; // need default
}

IMPLFUNC(onDestroy, WM_DESTROY)
{
	myUtil::testoutput("onDestroy");
	bRunning = false;
	PostQuitMessage(0);
	return 1;
}

IMPLFUNC(onBtnClick, WM_COMMAND)
{
	winBtn *pBtn = btnManager::Get()->getObjByMenu(LOWORD(wParam));
	if (NULL != pBtn){
		pBtn->OnButtonClick();
	}
	return 1;
}

IMPLFUNC(onPaint, WM_PAINT)
{
	PAINTSTRUCT ps;
	HDC hdc = BeginPaint(hwnd, &ps);
	HDC hdcMem = CreateCompatibleDC(hdc);
	int cxClient, cyClient;
	cxClient = ttMsgMap::Get()->m_msglpvar.m_cx;
	cyClient = ttMsgMap::Get()->m_msglpvar.m_cy;
	HBITMAP hBitmap = CreateCompatibleBitmap(hdc, cxClient, cyClient);
	SelectObject(hdcMem, hBitmap);

	//ttMsgMap::Get()->m_msglpvar.DrawMapToScreen(hdcMem, Me->getX() - cxClient/2, Me->getY() - cyClient/2);
	
	//draw proxy here
	for (ttClientPrxMgr::THISLIST::iterator iter = ttClientPrxMgr::Get()->getList().begin(); iter != ttClientPrxMgr::Get()->getList().end(); ++ iter){
		int tx = (*iter)->getX();
		int ty = (*iter)->getY();
		//(*iter)->draw(hdcMem, tx - Me->getX() + cxClient/2, ty - Me->getY() + cyClient/2);
	}
	
	//Me->draw(hdcMem, cxClient/2, cyClient/2);

	ttMsgMap::Get()->m_msglpvar.DrawMsg(hdcMem);

	BitBlt(hdc,0,0,cxClient,cyClient,hdcMem,0,0,SRCCOPY);
	DeleteObject(hBitmap);
	DeleteDC(hdcMem);
	EndPaint(hwnd, &ps);
	return 1;
}

IMPLFUNC(onSize, WM_SIZE)
{
	myUtil::testoutput("onSize");
	ttMsgMap::Get()->m_msglpvar.m_cx = LOWORD(lParam);
	ttMsgMap::Get()->m_msglpvar.m_cy = HIWORD(lParam);
	return 1;
}

IMPLFUNC(onTimer, WM_TIMER)
{
	timerManager::Get()->onTimer(hwnd, message, wParam, lParam);
	return 1;
}

IMPLFUNC(onKeyDown, WM_KEYDOWN)
{
    wParam = myUtil::transVK(wParam);
	myUtil::testoutput("onKeyDown");
	switch (wParam)
	{
	case VK_UP:
	case VK_DOWN:
        Me->setUDMoving(true);
        Me->setBtnUDDir(wParam);
        break;
    case VK_LEFT:
    case VK_RIGHT:
        Me->setLRMoving(true);
        Me->setBtnLRDir(wParam);
		break;
    case VK_ESCAPE:
        PostQuitMessage(0);
        break;
	}
	return 1;
}

IMPLFUNC(onKeyUp, WM_KEYUP)
{
    wParam = myUtil::transVK(wParam);
	switch (wParam)
	{
	case VK_UP:
	case VK_DOWN:
        Me->setUDMoving(false);
		break;
    case VK_LEFT:
    case VK_RIGHT:
        Me->setLRMoving(false);
        break;
	}
	return 1;
}

IMPLFUNC(onMouseMove, WM_MOUSEMOVE)
{
    int x = LOWORD(lParam);
    POINT pt = {x, 0};
    ClientToScreen(hwnd, &pt);
    int dx = myUtil::midCursor(pt.x, 0);

    Me->addDx(dx);
    return 1;
}

DEFWNDRPOC(msgProc)
{
	if (WM_KEYDOWN == message){
		if (VK_RETURN == LOWORD(wParam)){ 
			myUtil::testoutput("msgProc");

			ttMsgMap::_msgloopvar::msg Msg;
			::GetWindowText(hwnd, Msg.buf, 256);
			Me->speak(Msg.buf);

			ttMsgMap::_msgloopvar::pmsg pMsg = new ttMsgMap::_msgloopvar::msg;
			wsprintf(pMsg->buf, L"%s : %s", Me->getName(), Msg.buf);
			{
				autoLock lock(ttMsgMap::Get()->m_msglpvar.m_csMsgList);
				ttMsgMap::Get()->m_msglpvar.m_msglist.push_back(pMsg);
			}

			ttMsgMap::Get()->m_msglpvar.m_bMessaging = false;
			ShowWindow(ttMsgMap::Get()->m_msglpvar.m_hMsg, SW_HIDE);
			::SetWindowText(hwnd, L"");
		}
	}
	return 1;
}

DEFWNDRPOC(msgWndProc)
{
	switch (message)
	{
	case WM_DESTROY:
		PostQuitMessage(0);
		break;
	}
	return DefWindowProc(hwnd, message, wParam, lParam);
}